#ifndef __D3DCOMMON_H__
#define __D3DCOMMON_H__

#include <Windows.h>
#include <WindowsX.h>

#define _AFX_SECURE_NO_WARNINGS
#include <d3d11.h>
#include <D3D11Shader.h>
#include <D3Dcompiler.h>
#include <d3dx11.h>
#include <D3DX11async.h>
#include <xnamath.h>
#include <dxerr.h>

#include "Utility.h"

#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dx11.lib")
#pragma comment(lib, "D3DCompiler.lib")
#pragma comment(lib, "dxerr.lib")
#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "dxguid.lib")

namespace WindGE
{
	WIND_CORE_API D3DX11INLINE float LengthSquare(XMFLOAT3 pos0, XMFLOAT3 pos1)
	{
		//return (pos0.x*pos1.x + pos0.y*pos1.y + pos0.z*pos1.z);
		return (pos1.x - pos0.x)*(pos1.x - pos0.x) + (pos1.y - pos0.y)*(pos1.y - pos0.y) + (pos1.z - pos0.z)*(pos1.z - pos0.z);
	}

	WIND_CORE_API D3DX11INLINE XMMATRIX InverseTranspose(const XMMATRIX& M)
	{
		XMMATRIX A = M;
		A.r[3] = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);

		XMVECTOR det = XMMatrixDeterminant(A);

		return XMMatrixTranspose(XMMatrixInverse(&det, A));
	}

	WIND_CORE_API D3DX11INLINE XMMATRIX Inverse(const XMMATRIX& M)
	{
		return XMMatrixInverse(nullptr, M);
	}

	WIND_CORE_API D3DX11INLINE XMFLOAT3 Vec3MutiplyMatrix(const XMFLOAT3& vec, const XMMATRIX& trans)
	{
		XMVECTOR temp = XMLoadFloat3(&vec);
		temp = XMVector3TransformCoord(temp, trans);

		XMFLOAT3 vecTmp;
		XMStoreFloat3(&vecTmp, temp);
		return vecTmp;
	}

	WIND_CORE_API D3DX11INLINE void TransformToMatrix(XMFLOAT4X4& matrix, const XMFLOAT3& translate, const XMFLOAT3& rotate, const XMFLOAT3& scale)
	{
		XMVECTOR T = XMLoadFloat3(&translate);
		XMVECTOR R = XMLoadFloat3(&rotate);
		XMVECTOR RQuad = XMQuaternionRotationRollPitchYawFromVector(R);
		XMVECTOR S = XMLoadFloat3(&scale);
		XMVECTOR zero = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);
		XMMATRIX mat = XMMatrixAffineTransformation(S, zero, RQuad, T);
		XMStoreFloat4x4(&matrix, mat);
	}

	WIND_CORE_API D3DX11INLINE XMMATRIX TransformToMatrix(const XMFLOAT3& translate, const XMFLOAT3& rotate, const XMFLOAT3& scale)
	{
		XMVECTOR T = XMLoadFloat3(&translate);
		XMVECTOR R = XMLoadFloat3(&rotate);
		XMVECTOR RQuad = XMQuaternionRotationRollPitchYawFromVector(R);
		XMVECTOR S = XMLoadFloat3(&scale);
		XMVECTOR zero = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);
		return XMMatrixAffineTransformation(S, zero, RQuad, T);
	}

	WIND_CORE_API D3DX11INLINE XMMATRIX TransformToMatrix(const XMFLOAT3& translate, const XMFLOAT4& rotate, const XMFLOAT3& scale)
	{
		XMVECTOR T = XMLoadFloat3(&translate);
		XMVECTOR RQuad = XMLoadFloat4(&rotate);
		XMVECTOR S = XMLoadFloat3(&scale);
		XMVECTOR zero = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);
		return XMMatrixAffineTransformation(S, zero, RQuad, T);
	}

	WIND_CORE_API D3DX11INLINE void TransformToMatrix(XMFLOAT4X4& matrix, const XMFLOAT3& translate, const XMFLOAT4& rotate, const XMFLOAT3& scale)
	{
		XMVECTOR T = XMLoadFloat3(&translate);
		XMVECTOR RQuad = XMLoadFloat4(&rotate);
		XMVECTOR S = XMLoadFloat3(&scale);
		XMVECTOR zero = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);
		XMMATRIX mat = XMMatrixAffineTransformation(S, zero, RQuad, T);

		XMStoreFloat4x4(&matrix, mat);
	}
}

#endif	//__D3DCOMMON_H__